/* Developed by Daohang Shi dshi7@wisc.edu */

#ifndef CGRIP_H
#define CGRIP_H
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <queue>
#include <map>
#include <limits>
#include <cmath>
#include <cassert>
#include <algorithm>
#include <stdlib.h>
#include <limits.h>
#include <ctime>
#include <string.h>
#include <vector>
#include <stdint.h>

#include "Def.h"
#include "Auxf.h"
#include "Nodes.h"
#include "PNets.h"
#include "Pl.h"
#include "Shapes.h"
#include "Route.h"
#include "Parser_cplex.h"
#include "CGR.h"

using namespace std;

using std::vector;
using std::pair;
using std::cout;
using std::endl;
using std::string;
using std::map;
using std::numeric_limits;

/**
 * A structure to represent a 3D NetTerminal. Note the maximum values of x, y, z is determined from the routing grid.
 */
struct point3d
{
  /*@{*/
  uint32_t x ; /**< The x coordinate in the routing grid (>=0)*/
  uint32_t y ; /**< The y coordinate in the routing grid (>=0)*/
  uint32_t z ; /**< The z coordinate in the routing grid (>=0)*/
  /*@}*/
  point3d(uint32_t x1, uint32_t y1, uint32_t z1): x(x1),y(y1),z(z1){}
  point3d(): x(0),y(0),z(0){}
};
typedef struct point3d NetTerminal3D;
/**
 * A structure to represent a each node with its corresponing ranking.
 */
typedef struct{
  string name;
  int rank;
}nodeRank;

/**
 * A structure to represent a region on the grid.
 */
typedef struct{
  int llx; /**< The lower left x coordinate in the routing grid (>=0)*/
  int lly; /**< The lower left y coordinate in the routing grid (>=0)*/
  int width; /**< The width f the region in the routing grid (>=0)*/
  int height; /**< The height of the region in the routing grid (>=0)*/
  int of;		/**< The overflow of the region*/
  int cap; /**< The overall cap of the region*/
  int block; /**< Set if there is a blockage inside*/
  int boundry; /**< Set if the region is beside the boundries.*/
} regionStruct;

typedef vector<regionStruct> regionVector;

/*! \fn int CGP_readBenchmark(const char *fileName)
  \brief Read in the benchmark files and initialize the CGRIP. Note, you will not be running the CGRIP yet. 

  \param inAuxFile The benchmark name to read in.
  \returns 1 if successful, 0 otherswise(e.g. the input file is not valid) 
  */
int CGP_readBenchmark(const char *inAuxFile);

/*! \fn int CGP_readPlacement(const char *inPlFile)
  \brief Read in the placement file and initialize the coordinates. 
  The first line should always be "UCLA pl 1.0".
  After the first line, any line starting with a "#" is a comment and is ignored.
  This is followed neighbors[3] the coordinates of the nodes

  \param inPlFile he placement solution file to be read in.
  \returns 1 if successful, 0 otherswise(e.g. the input file is not valid) 
  */
int CGP_readPlacement(const char *inPlFile);

/*! \fn int CGP_setNodeCoordinate(const char *nodeName, const int llx, const int lly)
  \brief Set the coordinates of a moveable object.

  \param nodeName The name of the object to set the coordinates.
  \param llx The lower left x coordinate.
  \param lly The lower left y coordinate.
  \returns 1 if successful, 0 otherswise(e.g. the input name or coordinates are not valid) 
  */
int CGP_setNodeCoordinate(const char *nodeName, const int llx, const int lly);

/*! \fn CGP_runRouting(const int totalRunTime, const int resolution)
  \brief Run routing.

  \param totalRunTime. The total time limit for the cgrip routing in second.	Default is 900.
  \param resolution. The resolution for routing(>=1). For resolution 1, total overflow is minimized as in traditional routers.
  \returns 1 if successful, 0 otherswise(e.g. initialization is not correct.) 
  */
int CGP_runRouting(const char *inGRFile, int time_budget, std::ofstream &stream_file );

int runMode0 ( double stop_time, std::ofstream &stream_file );

int runMode1 ( double stop_time, std::ofstream &stream_file );

int runMode2 ( double stop_time, std::ofstream &stream_file );

int runMode3 ( double stop_time, std::ofstream &stream_file );

int runMode4 ( double stop_time, std::ofstream &stream_file );

int runMode5 ( double stop_time, std::ofstream &stream_file );

int runMode6 ( double stop_time, std::ofstream &stream_file );

int runMode7 ( double stop_time, std::ofstream &stream_file );

void  fixOneBox ( GridBox &b, std::ofstream &stream_file );

void  fixOneBox2 ( GridBox &b, std::ofstream &stream_file );

void  fixOneBox3 ( GridBox &b, std::ofstream &stream_file );

int runMode8 ( double stop_time, std::ofstream &stream_file );

#endif // CGRIP_H
